/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.opgea.token.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.opgea.token.dao.CompanyDAO;
import com.opgea.token.dao.DestinationDAO;
import com.opgea.token.dao.TokenDAO;
import com.opgea.token.dao.TokenDetailsDAO;
import com.opgea.token.domain.entities.Company;
import com.opgea.token.domain.entities.Destination;
import com.opgea.token.domain.entities.Token;
import com.opgea.token.domain.entities.TokenDetails;
import com.opgea.token.domain.qualifiers.TokenStatusQualifier;
import com.opgea.token.listeners.TokenContextLoaderListener;
import com.opgea.token.service.ApplicationService;
import com.opgea.token.service.TokenDetailsService;
import com.opgea.token.util.DateUtil;
import com.opgea.token.web.dto.TokenDetailsDTO;

/**
 * 
 * @author Ramesh
 */
@Service
@Transactional
public class TokenDetailsServiceImpl implements TokenDetailsService {

    @Autowired
    private TokenDetailsDAO tokenDetailsDAO;
    @Autowired
    private TokenDAO tokenDAO;
    @Autowired
    private DestinationDAO destinationDAO;
    @Autowired
    private CompanyDAO companyDAO;

    @Autowired
    private QmsSMSImpl smsService;

    @Autowired
    private ApplicationService applicationService;

    @Override
    public synchronized Integer getNextTokenNumber(Long companyId,
	    String dateString) {
	/*
	 * CurrentTokenModel currentToken =
	 * TokenContextLoaderListener.currentTokenMap.get(companyId); Date today
	 * = Calendar.getInstance(Locale.US).getTime(); Date currentTokenDate =
	 * currentToken.getToday();
	 * 
	 * SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); try{ today
	 * = sdf.parse(sdf.format(today)); currentTokenDate =
	 * sdf.parse(sdf.format(currentTokenDate)); }catch(ParseException pe){
	 * System
	 * .out.println("Application Service Exception>> getNextTokenNumber"
	 * +pe.getLocalizedMessage()); }
	 * 
	 * Integer nextTokenNumber = currentToken.getCurrentTokenNumber();
	 * if(today.compareTo(currentTokenDate) > 0 || nextTokenNumber == null){
	 * nextTokenNumber = 1; } else{ nextTokenNumber = nextTokenNumber+1; }
	 * currentToken.setCurrentTokenNumber(nextTokenNumber);
	 * currentToken.setToday(today); return nextTokenNumber;
	 */
	if (tokenDAO.getMaxTokenNumber(companyId, dateString) == null) {
	    return 1;
	} else {
	    return tokenDAO.getMaxTokenNumber(companyId, dateString) + 1;
	}
    }

    @Override
    public List<TokenDetailsDTO> findAll() {
	List<TokenDetails> tokenList = tokenDetailsDAO.findAll();
	List<TokenDetailsDTO> tokenDetailsList = new ArrayList<TokenDetailsDTO>();
	if (tokenList != null) {
	    for (TokenDetails tokenDetails : tokenList) {
		TokenDetailsDTO tdm = new TokenDetailsDTO();
		tdm.marshall(tokenDetails);
		tokenDetailsList.add(tdm);
	    }
	}

	return tokenDetailsList;
    }

    @Override
    public List<TokenDetailsDTO> findAllByCompanyId(Long companyId) {
	Company company = companyDAO.find(companyId);
	List<Token> tokenList = company.getTokenList();
	List<TokenDetailsDTO> tokenDetailsList = new ArrayList<TokenDetailsDTO>();

	if (tokenList != null) {
	    for (Token token : tokenList) {
		TokenDetails tokenDetails = token.getTokenDetails();
		TokenDetailsDTO tdm = new TokenDetailsDTO();
		tdm.marshall(tokenDetails);
		tokenDetailsList.add(tdm);
	    }
	}
	return tokenDetailsList;
    }

    @Override
    public List<TokenDetailsDTO> findAllByDestinationId(Long companyId,
	    Long destinationId) {
	List<TokenDetails> tokenDetailsList = tokenDetailsDAO
		.findAllByDestination(companyId, destinationId);
	List<TokenDetailsDTO> tokenDetailsDTOList = new ArrayList<TokenDetailsDTO>();

	if (tokenDetailsList != null) {
	    for (TokenDetails tokenDetails : tokenDetailsList) {
		TokenDetailsDTO tdm = new TokenDetailsDTO();
		tdm.marshall(tokenDetails);
		tokenDetailsDTOList.add(tdm);
	    }
	}
	return tokenDetailsDTOList;
    }

    @Override
    public TokenDetailsDTO create(TokenDetailsDTO tokenDetailsDTO) {
	TokenDetails tokenDetails = new TokenDetails();
	Token token = new Token();

	Company company = companyDAO.find(tokenDetailsDTO.getCompanyId());
	Destination destination = destinationDAO.find(new Long(tokenDetailsDTO
		.getDestinationId()));
	token.setTokenNo(this.getNextTokenNumber(company.getId(),
		tokenDetailsDTO.getAppointmentDate()));
	token.setCompany(company);
	token.setTokenDate(DateUtil.getDateFromYYYYMMDD(
		tokenDetailsDTO.getAppointmentDate(), "-"));

	tokenDAO.create(token);

	tokenDetailsDTO.unmarshall(tokenDetails);
	tokenDetails.setToken(token);
	tokenDetails.setDestination(destination);
	tokenDetailsDAO.create(tokenDetails);
	applicationService.addTokenStatus(tokenDetails);

	System.out.println("Token Context Loader Size..."
		+ TokenContextLoaderListener.currentTokenMap.size());

	/*
	 * Sending SMS Token Number to Mobile
	 * 
	 * try { smsService.sendTokenNo(tokenDetails.getMobileNo().toString(),
	 * tokenDetails.getToken().getTokenNo().toString()); } catch (Exception
	 * ex) {
	 * Logger.getLogger(ReceptionController.class.getName()).log(Level.
	 * SEVERE, null, ex); }
	 */

	tokenDetailsDTO.setTokenNo(token.getTokenNo().toString());
	return tokenDetailsDTO;
    }

    @Override
    public TokenDetailsDTO update(TokenDetailsDTO tokenDetailsDTO) {
	TokenDetails tokenDetails = null;
	if (tokenDetailsDTO.getId() != null && tokenDetailsDTO.getId() > 0) {
	    Destination destination = destinationDAO.find(tokenDetailsDTO
		    .getDestinationId());
	    tokenDetails = tokenDetailsDAO.find(tokenDetailsDTO.getId());
	    tokenDetailsDTO.unmarshall(tokenDetails);
	    tokenDetails.setDestination(destination);
	    tokenDetails
		    .setTokenStatus(TokenStatusQualifier.values()[tokenDetailsDTO
			    .getTokenStatus()]);
	    tokenDetails.setMetaData(tokenDetailsDTO.getMetaData());
	    tokenDetailsDAO.update(tokenDetails);
	    if (tokenDetailsDTO.getTokenStatus().equals(
		    TokenStatusQualifier.DONE.ordinal())) {
		applicationService.removeTokenStatus(tokenDetails);
	    } else {
		applicationService.updateTokenStatus(tokenDetails);
	    }
	} else {
	    this.create(tokenDetailsDTO);
	}

	return tokenDetailsDTO;
    }

    @Override
    public TokenDetailsDTO find(Long tokenDetailsId) {
	TokenDetails tokenDetails = tokenDetailsDAO.find(tokenDetailsId);
	TokenDetailsDTO tdm = new TokenDetailsDTO();
	tdm.marshall(tokenDetails);
	return tdm;
    }

    @Override
    public TokenDetailsDTO findByTokenId(Long tokenId) {
	Token token = tokenDAO.find(tokenId);
	TokenDetails tokenDetails = token.getTokenDetails();
	TokenDetailsDTO tdm = new TokenDetailsDTO();
	tdm.marshall(tokenDetails);
	return tdm;
    }

    @Override
    public List<TokenDetailsDTO> searchTokens(Long companyId, String searchKey,
	    String tokenDate) {
	List<TokenDetails> tokenDetailsList = tokenDetailsDAO.searchTokens(
		companyId, searchKey, tokenDate);
	List<TokenDetailsDTO> tokenDetailsDTOList = new ArrayList<TokenDetailsDTO>();
	if (tokenDetailsList != null) {
	    for (TokenDetails tokenDetails : tokenDetailsList) {
		TokenDetailsDTO tdm = new TokenDetailsDTO();
		tdm.marshall(tokenDetails);
		tokenDetailsDTOList.add(tdm);
	    }
	}

	return tokenDetailsDTOList;
    }

}
